<template>
  <view>
    <scroll-view
      class="scroll-view"
      scroll-x
      :enable-flex="true"
      scroll-with-animation
      scroll-anchoring
      :enhanced="true"
      :show-scrollbar="false"
      :scroll-into-view="`nav_${scrollIntoView}`"
    >
      <view class="pl-16"></view>
      <template v-for="(v, i) in tabsList" :key="v.id">
        <view
          :id="`nav_${v.id}`"
          class="h-32 br-22 px-12 mr-8 fz-14 scroll-view__item"
          :class="[activeIndex === i && 'scroll-view__item--active']"
          @click="handleTabItemClick(i)"
        >
          <text>{{ v.name || `报名者${i + 1}` }}</text>
          <view v-if="tabsList.length > 1" class="del-icon" @click.stop="handleDeLTab(i)">
            <text class="ali-icon">&#xe665;</text>
          </view>
        </view>
      </template>
      <view class="pl-16"></view>
    </scroll-view>
    <view
      class="form-list"
      :style="{ marginLeft: activeIndex ? -(windowWidth * activeIndex) + 'px' : 0 }"
    >
      <template v-for="v in tabsList" :key="v.id">
        <view v-if="formSchema.length" class="form-item">
          <SignUpInfoForm
            ref="signUpInfoFormRef"
            :schemas="formSchema"
            :values="v.formInfo"
            @schema-change="handleSchemaChange($event, v.id)"
          />
        </view>
      </template>
    </view>
    <Empty v-if="tabsList.length === 0" text="请添加人员信息" />
  </view>
</template>

<script setup lang="ts">
  import { computed, ref, watch } from 'vue';
  import { type TabItem, type SignUpInfoFormRef, type PersonnelInfoListRef } from './types';
  import { type FormSchema } from '@/components/Form';
  import { activityFormDetails, setHoldRegisterInfo } from '@/api/activity';
  import { IsInternalInterfaceEnum, IsRequired } from '@/enums/formEnum';
  import { localDataMapping } from '@/components/Form/hooks/useForm';
  import { propTypes } from '@/utils/propTypes';
  import SignUpInfoForm from './SignUpInfoForm.vue';
  import Empty from '@/components/Empty/Empty.vue';
  import type { OnchangeArgument } from '@/components/Form/types';
  import { isArray } from 'lodash-es';
  import { onUnload } from '@dcloudio/uni-app';
  import { memberTypeGetList } from '@/api/membership';
  import dictionary from '@/utils/dictionary';

  const windowWidth = computed(() => uni.getWindowInfo().windowWidth || 375);

  const props = defineProps({
    activityId: propTypes.number,
    purchaseQuantity: propTypes.number.def(1),
    buyMinNum: propTypes.number.def(1),
  });

  const emits = defineEmits(['update:purchaseQuantity']);

  const tabsList = ref<TabItem[]>([]);

  const signUpInfoFormRef = ref<SignUpInfoFormRef[]>([]);

  const activeIndex = ref(0);

  const scrollIntoView = ref<string>();

  function handleTabItemClick(index: number) {
    scrollIntoView.value = tabsList.value[index - 1 ? index : index - 1].id;
    activeIndex.value = index;
  }

  function handleDeLTab(index: number) {
    const list = tabsList.value.filter((_, i) => i !== index);
    const lastIndex = list.length - 1;
    tabsList.value = list;
    scrollIntoView.value = list[lastIndex].id;
    activeIndex.value = lastIndex;
    emits('update:purchaseQuantity', list.length);
  }

  const formSchema = ref<FormSchema[]>([]);
  const nameDataType = ref<FormSchema['dataType']>();

  async function getActivityFormItems() {
    const { activityId } = props;
    const r = await activityFormDetails(activityId);
    const basicInfo = r.customFormItemMap[0] || [];
    nameDataType.value = basicInfo[0].dataType;
    const activityInfo = r.customFormItemMap[1] || [];
    const schema: FormSchema[] = [];
    const typeDataName: { field: string; type: string }[] = [];
    const dictDataName: { field: string; type: string }[] = [];
    if (basicInfo.length) {
      schema.push({
        field: 'basicInfo',
        label: '基本信息',
        component: 'Divider',
      });
      basicInfo.forEach((v) => {
        const field = v.id.toString();
        schema.push({
          field,
          label: v.showName,
          component: v.itemType,
          dataType: v.dataType,
          dynamicDisabled: v.disabled,
          defaultValue: v.itemDefault,
          required: v.isRequired === IsRequired.REQUIRED,
          isOnChange: true,
          componentProps: {
            placeholder: v.value,
            limit: v.length,
            itemDefault: v.itemDefault,
            enableValue: v.enableValue,
            localdata: localDataMapping(v.customFormItemAnswerList, {
              label: 'words',
              value: 'id',
            }),
          },
        });
      });
    }

    if (activityInfo.length) {
      schema.push({
        field: 'activityInfo',
        label: '活动信息收集',
        component: 'Divider',
      });
      activityInfo.forEach((v, index) => {
        const field = v.id.toString();
        if (v.isInternalInterface === IsInternalInterfaceEnum.CLASSIFICATION && v.type) {
          typeDataName.push({ field, type: v.type });
        }
        if (v.isInternalInterface === IsInternalInterfaceEnum.DICTIONARY && v.type) {
          dictDataName.push({ field, type: v.type });
        }
        schema.push({
          field,
          label: v.showName,
          component: v.itemType,
          dataType: v.dataType,
          dynamicDisabled: v.disabled,
          defaultValue: v.itemDefault,
          required: v.isRequired === IsRequired.REQUIRED,
          isInternalInterface: v.isInternalInterface,
          ifShow(renderCallbackParams) {
            const { values, setFormModel, field } = renderCallbackParams;
            if (isArray(v.itemRelevanceAnsweIds)) {
              const bol = Object.values(values).some((val) => {
                return !!v.itemRelevanceAnsweIds?.find((id) => id == val);
              });
              if (!bol && setFormModel) {
                setFormModel({ field: field, value: void 0 });
              }
              return bol;
            }
            return true;
          },
          rulesMessageJoinLabel: false,
          componentProps: {
            placeholder: v.value,
            limit: v.length,
            itemDefault: v.itemDefault,
            enableValue: v.enableValue,
            localdata: localDataMapping(v.customFormItemAnswerList, {
              label: 'words',
              value: 'id',
            }),
          },
        });
      });
    }

    const td = typeDataName;
    const dd = dictDataName;
    const localdataMap: { [x: string]: any[] } = {};
    if (td.length) {
      const res = await memberTypeGetList(td.map((v) => v.type));
      for (let index = 0; index < td.length; index++) {
        const item = td[index];
        const localdata = localDataMapping(res[item.type], { label: 'name', value: 'id' });
        localdataMap[item.field] = localdata;
      }
    }
    if (dd.length) {
      const dictList = await dictionary.getMulti(dd.map((v) => v.type));
      for (let index = 0; index < dd.length; index++) {
        const item = dd[index];
        const localdata = localDataMapping(dictList[item.type], {
          label: 'dictLabel',
          value: 'dictValue',
        });
        localdataMap[item.field] = localdata;
      }
    }
    schema.forEach((v) => {
      const key = v.field;
      if (localdataMap[key]) {
        v.componentProps = {
          ...v.componentProps,
          localdata: localdataMap[key],
        };
      }
    });

    formSchema.value = schema as any[];
  }

  function handleSchemaChange(e: OnchangeArgument, id: string) {
    if (e.dataType === nameDataType.value) {
      const item = tabsList.value.find((v) => v.id === id);
      item && (item.name = e.val);
    }
  }

  watch(
    () => props.activityId,
    (val) => val && getActivityFormItems(),
    { immediate: true },
  );

  defineExpose<PersonnelInfoListRef>({
    addPerson: (data) => {
      tabsList.value.push(data);
      emits('update:purchaseQuantity', tabsList.value.length);
      handleTabItemClick(tabsList.value.length - 1);
    },
    getPersonNum: () => tabsList.value.length,
    setHoldInfo: (list: TabItem[]) => {
      tabsList.value = list;
      emits('update:purchaseQuantity', tabsList.value.length);
    },
    clearHoldInfo: () => {
      clearHoldInterval();
    },
    getFieldsValue: async () => {
      const aIndex = activeIndex.value;
      const domRefs = isArray(signUpInfoFormRef.value) ? signUpInfoFormRef.value : [];
      const length = domRefs.length;

      // if (purchaseQuantity !== length) {
      //   let msg = '报名人数和购票数量不一致, 请调整购票数量';
      //   uni.showModal({ title: '提示', content: msg, showCancel: false });
      //   return Promise.reject(new Error(msg));
      // }
      if ((props.buyMinNum && length < props.buyMinNum) || length === 0) {
        let msg = `最少报名${props.buyMinNum || 1}位`;
        uni.showModal({ title: '提示', content: msg, showCancel: false });
        return Promise.reject(new Error(msg));
      }

      const values = [];
      await domRefs[aIndex].submit();
      for (let index = 0; index < length; index++) {
        const item = domRefs[index];
        if (!item) continue;
        await domRefs[index].submit().catch((err) => {
          handleTabItemClick(index);
          return Promise.reject(err);
        });
        const vals = item.getFieldsValue();
        values.push(vals);
      }

      return values;
    },
  });

  const holdTimer = ref<NodeJS.Timeout>();
  function setHoldInfo() {
    holdTimer.value = setInterval(async () => {
      const domRefs = isArray(signUpInfoFormRef.value) ? signUpInfoFormRef.value : [];
      const length = tabsList.value.length;
      if (length === 0 || !props.activityId) return;
      const values: TabItem[] = [];
      for (let index = 0; index < length; index++) {
        const item = tabsList.value[index];
        const formItemRef = domRefs[index];
        if (!item || !formItemRef) continue;
        const vals = formItemRef.getFieldsValue();
        values.push({
          ...item,
          formInfo: vals,
        });
      }
      await setHoldRegisterInfo(props.activityId, JSON.stringify(values));
      console.log('报名信息自动暂存成功');
    }, 3000);
  }

  setHoldInfo();

  function clearHoldInterval() {
    clearInterval(holdTimer.value);
    holdTimer.value = void 0;
  }

  onUnload(() => {
    clearHoldInterval();
  });
</script>

<style lang="scss" scoped>
  .scroll-view {
    display: flex;
    height: 84rpx;

    &__item {
      flex-shrink: 0;
      height: 64rpx;
      background-color: #f2f3f5;
      color: #646566;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
      margin-top: 20rpx;
      &:nth-last-child(1) {
        margin: 0;
      }
      .del-icon {
        font-size: 32rpx;
        width: 40rpx;
        height: 40rpx;
        position: absolute;
        right: -20rpx;
        top: -20rpx;
        color: #c8cacc;
      }
    }
    &__item--active {
      background-color: #2878ff;
      color: #fff;
    }
  }

  .form-list {
    display: flex;
    transition: 0.3s;
    .form-item {
      width: 100vw;
      flex-shrink: 0;
    }
  }
</style>
